package com.tiny.tests;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import com.tiny.core.game.Game;
import com.tiny.core.game.GameObject;
import com.tiny.core.game.util.MovimentCalculator;
import com.tiny.core.input.KeyboardManager;
import com.tiny.core.physics.CollisionDetector;
import com.tiny.core.physics.PhysicGameObject;
import com.tiny.core.physics.SimpleGravityManager;
import com.tiny.core.physics.Vector;
import com.tiny.tests.common.StaticWall;

public class CannonGame extends Game {

    private Cannon cannon;
    private SimpleGravityManager gravityManager;
    private List<PhysicGameObject> cannonBalls;
    private List<GameObject> objs;
    private CollisionDetector collisionDetector;

    @Override
    public void onLoad() {
        cannon = new Cannon(100, 530, 20, 50);

        objs = new ArrayList<GameObject>();

        objs.add(new StaticWall(5, 30, 10, getHeight() - 50));
        objs.add(new StaticWall(getWidth() - 15, 30, 10, getHeight() - 50));
        objs.add(new StaticWall(10, 30, getWidth() - 20, 10));
        objs.add(new StaticWall(5, getHeight() - 30, getWidth() - 20, 10));

        cannonBalls = new ArrayList<PhysicGameObject>();
        gravityManager = new SimpleGravityManager(cannonBalls, 0.5);
        collisionDetector = new CollisionDetector(objs);
    }

    @Override
    public void onUnload() {
    }

    List<GameObject> toRemove = new ArrayList<GameObject>();
    @Override
    public void onUpdate(int currentTick) {
        gravityManager.update();
        collisionDetector.update();

        cannon.update(currentTick);

        if (KeyboardManager.getInstance().isPressed(KeyEvent.VK_SPACE)) {
            CannonBall ball = new CannonBall((int) cannon.getPos().x,
                    (int) cannon.getPos().y, getMovimentCalculator());

            ball.setMass(2.0d);
            ball.setVelocity(new Vector(cannon.getForce(), cannon.getPower()));
            objs.add(ball);
            cannonBalls.add(ball);
        }

        
        for (GameObject o : objs) {
            o.update(currentTick);
            if (o.getEnergy() < 0) {
                toRemove.add(o);
            }
        }
        objs.removeAll(toRemove);
        cannonBalls.removeAll(toRemove);

        if (KeyboardManager.getInstance().isHold(KeyEvent.VK_ESCAPE)) {
            terminate();
        }
    }

    @Override
    public void onRender(Graphics2D g) {
        cannon.render(g);
        for (GameObject o : objs) {
            o.render(g);
        }
        g.setColor(Color.WHITE);
        g.drawString("Force: " + cannon.getForce(), 10, 10);
        g.drawString("Power: " + (cannon.getPower() * -1), 10, 25);
    }

    @Override
    public String getTitle() {
        return "Cannon";
    }

    public static void main(String[] args) {
        new CannonGame().run();
    }
}

// Objects os the game
class Cannon extends GameObject {

    private Double force = 0d;
    private Double power = -20d;

    public Cannon(int x, int y, int width, int height) {
        super(x, y, width, height);
    }

    public Double getForce() {
        return force;
    }

    public void setForce(Double force) {
        this.force = force;
    }

    public Double getPower() {
        return power;
    }

    public void setPower(Double power) {
        this.power = power;
    }

    @Override
    public void update(int currentFrame) {
        if (KeyboardManager.getInstance().isPressed(KeyEvent.VK_RIGHT)) {
            force += 0.5d;
        }

        if (KeyboardManager.getInstance().isPressed(KeyEvent.VK_LEFT)) {
            force -= 0.5;
        }

        if (KeyboardManager.getInstance().isPressed(KeyEvent.VK_UP)) {
            power -= 0.5;
        }

        if (KeyboardManager.getInstance().isPressed(KeyEvent.VK_DOWN)) {
            power += 0.5d;
        }
    }

    @Override
    public void render(Graphics2D g) {
        g.setColor(Color.WHITE);
        g.fillRect((int) pos.x, (int) pos.y, (int) pos.width, (int) pos.height);
    }
}

class CannonBall extends PhysicGameObject {

    public CannonBall(int x, int y, MovimentCalculator calc) {
        super(x, y, 15, 15, calc);
    }

    @Override
    public void onUpdate(int currentFrame) {
        if (isStopped()) {
            setEnergy(-1);
        }

        setOnGround(collidingEntities[COLLIDING_BELOW] != null);
        if (collidingEntities[COLLIDING_ABOVE] != null || collidingEntities[COLLIDING_BELOW] != null) {
            getVelocity().setY(getVelocity().getY() - getMass());
            invertVelocityY();
            fixCollidingPosition();
        }
        if (collidingEntities[COLLIDING_LEFT] != null || collidingEntities[COLLIDING_RIGHT] != null) {
            invertVelocityX();
            fixCollidingPosition();
        }
    }

    @Override
    public void render(Graphics2D g) {
        g.setColor(Color.WHITE);
        g.fillOval((int) getPos().x, (int) getPos().y, (int) getPos().width,
                (int) getPos().height);
    }
}
